import express from 'express';
const reCommitRouter = express.Router();
import { checkTodayWhereCommit } from '../../utils/checkTodayWhereCommit';

/**
 * 建立即时通讯连接, 每次补交推送后都发射事件给客户端.
 */
const WebSocketServer = require('ws').Server;
const wss = new WebSocketServer({ port: process.env.WS_PORT });
wss.on('connection', function connection(_ws: any) {});

// 发射事件
function sendMessage(messageJson: { day: string; count: number }) {
	wss.clients.forEach(function each(client: any) {
		if (client.readyState === 1) {
			client.send(JSON.stringify(messageJson));
		}
	});
}

/**
 * 补交: 补交指定日期的提交记录.
 *
 * query:
 *  - startDate: 开始日期, 默认昨天.
 *  - endDate: 结束日期, 默认昨天.
 *  - commitCount: 补交次数 -> {number:固定值, random:随机值}
 *  - randomScope: 随机数范围
 *     + ,分隔 -> 传参错误则从1~30取随机值.
 *     + 第一个数如果传递0, 则可能此次不提交.
 */
reCommitRouter.get('/', async (req, res) => {
	const yesterday = moment_g().subtract(1, 'days').format('YYYY-MM-DD');
	const initRandomMin = 1;
	const initRandomMax = 30;
	const initRandomStr = `${initRandomMin},${initRandomMax}`;

	// 接收参数
	let startDate = <string>req.query.startDate ?? yesterday;
	let endDate = <string>req.query.endDate ?? yesterday;
	let commitCount = <number | 'random'>req.query.commitCount ?? 'random';
	let randomScope = <string>req.query.randomScope ?? initRandomStr;

	// 随机数范围
	let randomStart = initRandomMin;
	let randomEnd = initRandomMax;
	commitCount = commitCount === 'random' ? 'random' : Number(commitCount);

	// 校验及处理参数
	try {
		// 日期是否合法
		if (!(moment_g(startDate).isValid() && moment_g(endDate).isValid())) {
			return res.json(formatResJson({ code: 'Fail', msg: '日期格式不合法!' }));
		}
		// 开始日期是否在结束日期之后
		if (moment_g(startDate).isAfter(moment_g(endDate))) {
			return res.json(formatResJson({ code: 'Fail', msg: '开始日期不能在结束日期之后!' }));
		}

		// 校验提交次数:固定值
		if (commitCount !== 'random') {
			// 固定值不是数字.
			if (isNaN(commitCount)) {
				return res.json(formatResJson({ code: 'Fail', msg: 'commitCount参数不合法!' }));
			}
			if (commitCount < 1 || commitCount > 30) commitCount = 1;
		}
		// 校验提交次数:随机值
		if (commitCount === 'random') {
			// 提交的随机值范围没有分隔符, 恢复默认值.
			if (!randomScope.includes(',')) randomScope = initRandomStr;

			let [start, end] = randomScope.split(',');
			let num_start = Number(start);
			let num_end = Number(end);

			if (!isNaN(num_start) && num_start >= 0) randomStart = num_start;
			if (!isNaN(num_end) && num_end <= 30) randomEnd = num_end;
		}
	} catch (e) {
		return res.json(formatResJson({ code: 'Fail', msg: '校验参数发生异常!' }));
	}

	// 开始提交
	while (moment_g(startDate).isSameOrBefore(moment_g(endDate))) {
		// 判断今天是否需要提交
		if (!checkTodayWhereCommit(startDate)) {
			sendMessage({ day: startDate, count: 0 });
			startDate = moment_g(startDate).add(1, 'days').format('YYYY-MM-DD');
			continue;
		}

		try {
			// 最终的提交次数
			let commitCountVal = 0;

			// 从1~30随机数
			if (commitCount === 'random') {
				commitCountVal = Math.floor(Math.random() * (randomEnd - randomStart + 1)) + randomStart;
			} else {
				commitCountVal = commitCount;
			}

			// 在次日, 重复提交N次.
			for (let i = 0; i < commitCountVal; i++) {
				await updateTargetFile(res, {
					commit_options: {
						'--amend': null,
						'--date': `${startDate}T12:00:00`,
					},
				});

				try {
					await git.push('origin', 'master', { '--force': null });
				} catch (e: any) {
					return res.json(
						formatResJson({ code: 'Fail', msg: `推送目标文件内容失败:${e?.message}}` })
					);
				}

				await new Promise((resolve) => setTimeout(resolve, Number(process.env.COMMIT_INTERVAL_MS)));
			}

			sendMessage({ day: startDate, count: commitCountVal });
		} catch (e: any) {
			return res.json(formatResJson({ code: 'Fail', msg: `补交失败:${e?.message}}` }));
		}

		// 开始日期加1天
		startDate = moment_g(startDate).add(1, 'days').format('YYYY-MM-DD');
	}

	return res.json(formatResJson({ msg: '补交成功!' }));
});

module.exports = reCommitRouter;
